package com.gitee.wsl.logger.format

import com.gitee.wsl.logger.LogFormatter
import com.gitee.wsl.logger.LogLevel
import com.gitee.wsl.logger.Logger
import java.lang.StringBuilder

/***
 * 漂亮的LogTxt日志输出格式:
 * 2023-07-22 14:16:34.284 30117-30117/com.october. Logger D/TestLogger:
 *  ┌──────────────────────────
 *  │ Method stack history
 *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
 *  │ Thread information
 *  ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
 *  │ Log message
 *  └──────────────────────────
 */
open class LogTxtPrettyFormat : LogFormatter {
    override fun format(
        level: LogLevel,
        tag: String,
        messageAny: Any?,
        throwable: Throwable?,
    ): String {
        val builder = StringBuilder()
        /*builder.append(getNowTimeStr()) //时间
        builder.append(" ")
        builder.append(getPid()) //Pid
        builder.append("-")
        builder.append(getTid()) //Tid
        builder.append("/")
        builder.append(PACKAGE_NAME) //包名
        builder.append(" ")
        builder.append(logLevel.describe) //日志级别
        builder.append("/")
        builder.append(tag)  //tag
        builder.append(":")*/

        val space = "    "
        builder.append("\n")
        builder.append("${space}$TOP_BORDER\n")
        builder.append("${space}$HORIZONTAL_LINE ${getMethodTask()}     \n")
        builder.append("${space}$MIDDLE_BORDER\n")
        builder.append("${space}$HORIZONTAL_LINE Thread:${Thread.currentThread().name} (${Thread.currentThread().id})\n")
        builder.append("${space}$MIDDLE_BORDER\n")
        if(throwable != null){
            val errorMsg = getStackTraceStringWithPrefix(throwable,"$space$HORIZONTAL_LINE")
            builder.append(errorMsg)
        }else{
            builder.append( "${space}$HORIZONTAL_LINE ${messageAny}\n" )
        }
        builder.append("${space}$BOTTOM_BORDER\n")
        return builder.toString()
    }

    open fun getMethodTask():String{
        val elements = Throwable().stackTrace
        val index = elements
            .indexOfFirst {
                it.className !in fqcnIgnore
            }.let {
                return@let it + 6
            }
        val element =  elements[index]
        val elementMsg ="${element.className}#${element.methodName}(${element.fileName}:${element.lineNumber})"
        return elementMsg
    }

    open fun builderThrowableMsg(throwable: Throwable):Any{
        val thrMsg = getStackTraceStringWithPrefix(throwable, HORIZONTAL_LINE.toString())
        return thrMsg
    }

     open fun getStackTraceStringWithPrefix(thr: Throwable, s: String): Any{
         return s
     }

    private val fqcnIgnore = listOf(Logger::class.java.name)

    companion object{
        private const val TOP_LEFT_CORNER = '┌'
        private const val BOTTOM_LEFT_CORNER = '└'
        private const val MIDDLE_CORNER = '├'
        private const val HORIZONTAL_LINE = '│'
        private const val DOUBLE_DIVIDER = "────────────────────────────────────────────────────────"
        private const val SINGLE_DIVIDER = "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄"
        private const val TOP_BORDER = TOP_LEFT_CORNER.toString() + DOUBLE_DIVIDER + DOUBLE_DIVIDER
        private const val BOTTOM_BORDER = BOTTOM_LEFT_CORNER.toString() + DOUBLE_DIVIDER + DOUBLE_DIVIDER
        private const val MIDDLE_BORDER = MIDDLE_CORNER.toString() + SINGLE_DIVIDER + SINGLE_DIVIDER
    }
}

